/*******************************************
数据传输编码与解码
*******************************************/


#ifndef __DATA_TRANS_EN_DECODE_F_H__
#define __DATA_TRANS_EN_DECODE_F_H__

#include "comm_lib_f.h"

#ifndef __cplusplus
//#define __cplusplus
#endif

#ifdef __cplusplus
//extern "C" {
#endif //


typedef void*			dpkg_handle;


//Catch package status,we can only check the return value of the function dpkg_catch_package
//equals to CPS_COMPLETE,to indicate our package is ready.
//
//For advance,we can check if the return value is CPS_LOCKED,to determine if there is some byte lose
//because of we have not call dpkg_get_package in time.
//
//And we can check CPS_ERROR in return value to got an error
typedef enum _CatchPackageStatus
{
	CPS_ERROR			=0,			//input is invalid that we throw the input,and the CPS is initial as CPS_ERROR
	CPS_CATCHING		,			//the input is valid,in the process of collecting input
	CPS_COMPLETE		,			//a valid package is catch complete
	CPS_LOCKED			,			//because of the user have not handle the current package,lock the buffer to prevent it be damaged
	CPS_MAX
//	CPS_DATA_ERROR
}eCatchPackageStatus_t;


//get a dpkg_handle,pass it at the below functions.
//we also can pass a global dpkg_operator_t to the below functions.
//is we use a global dpkg_operator_t,remember to call dpkg_init() first.
dpkg_handle dpkg_open();
//only can release the handle that open by dpkg_open()
void dpkg_close(dpkg_handle hDP);

void dpkg_init(dpkg_handle dpkg);

//This function use in serial "get byte interrupt".
//If your serial have not so call "get byte interrupt" but
//just a got something interrupt,please make the get byte interrupt yourself.
//Anyhow,every byte we got,pass to DPKG_CatchPackage and check the result.
//return value's type is eCatchPackageStatus_t
U8 dpkg_catch_package(dpkg_handle hDP,U8 uByte);

//When DEN_CatchPackage returns CPS_COMPLETE,continue call
//DEN_CatchPackage will returns CPS_LOCKED.
//Till we call DEN_GetPackage to get the result,
//the status will be unlock and we can start a new DPKG_CatchPackage
BOOL dpkg_get_package(dpkg_handle hDP,U8* pData,U16* pwLen);

//DEN_IsBusy will return true when the status is locked.
BOOL dpkg_isbusy(dpkg_handle hP);


//pIn		要输入的内容
//inLen	要输入的长度
//pOut		输出的内容
//outLen	输出的长度
void dpkg_package(const void * pIn,U16 inLen,void * pOut,U16* pOutLen);
BOOL dpkg_unpackage(const void * pIn,U16 inLen,void * pOut,U16* pOutLen);

typedef void* (*dpkg_malloc  )(size_t __size);
typedef void  (*dpkg_free)(void *__ptr);

//dpkg_open and close may cause a malloc and free be called.
//in the embedded system,usually,we have our allocation solution
//use the function below to set your own allocation.
void dpkg_setalloc(dpkg_malloc fn1,dpkg_free fn2);

//reset the allocation to malloc and free
void dpkg_resetalloc(void);

#ifdef __cplusplus
//}
#endif //



#ifdef __cplusplus
class data_packagef_t
{
protected:
	dpkg_handle		_pkg;

public:
	data_packagef_t(){_pkg = dpkg_open();}
	~data_packagef_t(){dpkg_close(_pkg);}

	U8 catch_package(U8 uByte){return dpkg_catch_package(_pkg,uByte);}
	BOOL get_package(U8* pData,U16* pwLen){return dpkg_get_package(_pkg,pData,pwLen);}
	BOOL isbusy(){return dpkg_isbusy(_pkg);}

	static void package(const void* pIn,U16 inLen,void* pOut,U16* outLen)
	{dpkg_package(pIn,inLen,pOut,outLen);}
	static BOOL unpackage(const void * pIn,U16 inLen,void * pOut,U16* outLen)
	{return dpkg_unpackage(pIn,inLen,pOut,outLen);}
};
#endif //__cplusplus

#include "data_package_impl_f.h"

#endif //__DATA_TRANS_EN_DECODE_F_H__
